package com.billard.handler;

import com.billard.exception.BataException;
import com.billard.exception.MessageConstant;
import com.billard.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * 全局异常处理器，处理项目中抛出的业务异常
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    // 业务异常
    @ExceptionHandler(BataException.class)
    public Result<Void> handleBusinessException(BataException ex) {
        // 记录完整的异常堆栈信息
        String locationInfo = "未知位置";
        if (ex.getStackTrace().length > 0) {
            StackTraceElement element = ex.getStackTrace()[0];
            locationInfo = element.getClassName() + ".java" + ", 行号: " + element.getLineNumber();
        }
        log.info("业务异常: {} (发生在: {})", ex.getMessage(), locationInfo);
        return Result.error(400, ex.getMessage());
    }

    // 权限不足异常
    @ExceptionHandler(AccessDeniedException.class)
    public Result<Void> handleAccessDeniedException(AccessDeniedException ex) {
        // 获取异常发生的位置信息
        String locationInfo = "未知位置";
        if (ex.getStackTrace().length > 0) {
            StackTraceElement element = ex.getStackTrace()[0];
            locationInfo = element.getClassName() + ".java" + ", 行号: " + element.getLineNumber();
        }
        // 记录包含位置信息的异常日志
        log.warn("权限不足异常: {} (发生在: {})", ex.getMessage(), locationInfo);
        return Result.error(403, "权限不足，无法访问该资源");
    }

    // SQL 错误
    @ExceptionHandler(SQLException.class)
    public Result<Void> handleSQLException(SQLException ex) {
        // 记录完整的异常堆栈信息
        String locationInfo = "未知位置";
        if (ex.getStackTrace().length > 0) {
            StackTraceElement element = ex.getStackTrace()[0];
            locationInfo = element.getClassName() + ".java" + ", 行号: " + element.getLineNumber();
        }
        log.error("数据库错误: {} (发生在: {})", ex.getMessage(), locationInfo);
        return Result.error(500, "数据库错误: " + ex.getMessage());
    }

    // 兜底
    @ExceptionHandler(Exception.class)
    public Result<Void> handleException(Exception ex) {
        // 已包含完整异常堆栈，保持不变
        // 获取异常发生的位置信息
        String locationInfo = "未知位置";
        if (ex.getStackTrace().length > 0) {
            StackTraceElement element = ex.getStackTrace()[0];
            locationInfo = element.getClassName() + ".java" + ", 行号: " + element.getLineNumber();
        }
        log.error("服务器内部错误: {} (发生在: {})", ex.getMessage(), locationInfo);
        return Result.error(500, "服务器内部错误: " + ex.getMessage());
    }
}
